﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace complier
{
    class Program
    {
        private static void Main(string[] args)
        {

            //打印单词表
            string path = "D://test//chengxu2.cpp";
            int i = 0;
            var complier = new Complier();

            Console.Write("\n-------------------词法分析-------------------\n");
            //词法分析 程序 
            complier.TokenAnalysis(path);
            //词法分析结果输出 
            Console.WriteLine("\t序号\t单词\t类型\t行号");

            for (i = 0; i < complier.Table.realNum; i++)
            {
                var token = "";
                //char[]转string
                foreach (var ch in complier.Table.list[i].str.Where(o => o != '\0'))
                {
                    token += ch;
                }
                Console.WriteLine("\t{0}\t{1}\t{2}\t{3}",
                    i + 1,
                    token,
                    complier.Table.list[i].ttype,
                    complier.Table.list[i].linenum);
            }
            int t = 0;
            for (t = 0; t < 2; t++)
            {
                Console.WriteLine(complier.PSanf[0].str);
            }
            Console.WriteLine("-----------------语法分析(自顶向下)：-------------------\n\n");
            complier.parse();
            Console.WriteLine("-----------------语义分析和汇编代码生成：----------------\n");
            complier.code();
            Console.ReadKey();
        }

    }
    /// <summary>
    /// 编译器类
    /// </summary>
    internal class Complier
    {
        #region 词法语法分析所需变量
        public const int MAXLENTH = 2048;
        public const int MAXNUM = 512;
        public const int IDLENGTH = 126;
        public const int MAXVARTABLENUM = 512;
        public const int SIYUANSHI = 10;
        public const int MAXSIYUANSHI = 500;
        /*
         结构体的数组部分，必须用MarshalAs转换到非托管类型
         它指示如何在托管代码与非托管代码之间封送数据
         用法:
         struct Variable
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] char[] variable;

        }
         更多详情：https://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.marshalasattribute(v=vs.110).aspx
         */
        /// <summary>
        /// 变量结构体
        /// </summary>
        public struct Variable
        {
            /// <summary>
            /// 变量
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXNUM)]
            public char[] variable;
        }
        /// <summary>
        /// 输入输出数据结构
        /// </summary>
        public struct printfAndscanf
        {
            public int id;
            /// <summary>
            ///数组 vars[MAXLENTH]的实际长度 
            /// </summary>
            public int varindex;
            public int log;//1代表输出，2代表输入 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXLENTH)]
            public char[] str;//引号内的字符
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXLENTH)]
            public Variable[] vars;
        }

        int PSindex = 0; //PSanf[MAXNUM]数组的下标值 
        //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXNUM)]
        public printfAndscanf[] PSanf = new printfAndscanf[MAXNUM];
        //单词
        public enum TokenType
        {
            //关键字           
            IF, ELSE, WHILE, RETURN, VOID, INT, FLOAT, DOUBLE, CHAR, CONST, SWITCH, CASE, BREAK, DO, FOR,
            //运算符 +  -       *    /       =    <  <=  >  >=    !  !=  ==  ++     -- 
            PLUS, MINUS, STAR, SLASH, ASSIGN, LT, LTEQ, GT, GTEQ, NEG, NEQ, EQ, PLUS_2, MINUS_2,
            //界符 ;     ,    (      )      [      ]      {      }   
            SEMI, COMMA, LPAREN, RPAREN, LSQUAR, RSQUAR, LBRACE, RBRACE,
            COMMENT,   //注释
            ID,                             //标识符
            NUMBER,                         //数字常量
            NONTOKEN, ERROR, ENDFILE,  // 其它 
            OPERATOR,   //&与运算符 
            PRINTF,     //输出 
            SCANF,      //输入 
            POINT,//百分号
            QMARKS,		//双引号
            NULL//新增NULL作为初始化用
        }

        ///// <summary>
        ///// 单词类型
        ///// </summary>
        //string[] type = new string[] {

        //    //关键字 
        //    "IF","ELSE","WHILE","RETURN","VOID","INT","FLOAT","DOUBLE","CHAR","CONST","SWITCH","CASE","BREAK","DO","FOR",
        //	//运算符 +      -       *      /       =       <     <=    >    >=     !     !=   ==    ++       --  
        //	"PLUS","MINUS","STAR","SLASH","ASSIGN","LT","LTEQ","GT","GTEQ","NEG","NEQ","EQ","PLUS_2","MINUS_2",
        //	//界符   ;       ,      (        )        [         ]       {         }      /*  */
        //	"SEMI","COMMA","LPAREN","RPAREN","LSQUAR","RSQUAR","LBRACE","RBRACE",
        //    "COMMENT",   //注释
        //	"ID",                             //标识符
        //	"NUMBER",                         //数字常量
        //	"NONTOKEN","ERROR","ENDFILE", // 其它  
        //	"OPERATOR",//& 
        //	"PRINTF",

        //    "SCANF",

        //    "POINT",//%
        //	"QMARKS"//"

        //};

        /// <summary>
        /// 17个保留字
        /// </summary>
        public struct reservedword
        {
            public string str;
            public TokenType tok;
        }
        public reservedword[] reservedwords = new reservedword[]
        {
            new reservedword() { str="if", tok=TokenType.IF },
            new reservedword() { str="else", tok=TokenType.ELSE },
            new reservedword() { str="while", tok=TokenType.WHILE },
            new reservedword() { str="return", tok=TokenType.RETURN },
            new reservedword() { str="void", tok=TokenType.VOID },
            new reservedword() { str="int", tok=TokenType.INT },
            new reservedword() { str="float", tok=TokenType.FLOAT },
            new reservedword() { str="double", tok=TokenType.DOUBLE },
            new reservedword() { str="char", tok=TokenType.CHAR },
            new reservedword() { str="const", tok=TokenType.CONST },
            new reservedword() { str="switch", tok=TokenType.SWITCH },
            new reservedword() { str="case", tok=TokenType.CASE },
            new reservedword() { str="break", tok=TokenType.BREAK },
            new reservedword() { str="do", tok=TokenType.DO },
            new reservedword() { str="for", tok=TokenType.FOR },
            new reservedword() { str="printf", tok=TokenType.PRINTF },
            new reservedword() { str="scanf", tok=TokenType.SCANF },
        };

        /// <summary>
        /// 缓存单词
        /// </summary>
        public enum scanState
        {
            //运算符 + - * /  =  <  <=  >  >=  !=  == … 
            INPLUS, INMINUS, INSTAR, INSLASH, INASSIGN, INLT, INLTEQ, INGT, INGTEQ, INNEQ, INEQ,
            //界符 ;  ,  (  )  [  ]  {  }  /*  */
            INSEMI, INCOMMA, INLPAREN, INRPAREN, INLSQUAR, INRSQUAR, INLBRACE, INRBRACE,
            INLCOMMENT, INRCOMMENT,
            INID,                           //标识符
            INNUM,                  //数字常量
            START, DONE,
            INLINE   //下划线 
        }
        
        //单词符号的数据结构设计
        public struct Token
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXNUM)]
            public string str; //单词字符串
            public TokenType ttype; //单词的类型
            public int linenum; //所在行号信息
        }


        //单词表
        public struct TokenTable
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXNUM)]
            public Token[] list; //存放单词的列表
            public int index;//单词索引
            public int realNum;//实际单词数量
        }

        public TokenTable Table;

        //存储输入缓存字符串
        public struct SrcBuf
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXLENTH)]

            public char[] srcBuf; //存储输入内容
            public int index; //单个字符索引
            public int realLenth; //缓冲区实际长度
        }

        SrcBuf Inbuf;
        private int[] lineNum = new int[MAXLENTH];
        int index = 0;//判断double类型有多少个. 

        /*  第二部分*/
        [StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)]
        public struct __TreeNode
        {
            public int lineno;
            public string nodestr; //保存标识符的名称，便于在语法中显示
            public string vartype; //用于标明变量类型int char float
            public string rettype; //函数返回类型void int char float
        };
        //语法节点数据结构
        public __TreeNode TreeNode;
        public __TreeNode pTreeNode;

        Token curtoken;//当前字符


        #endregion
        #region 语义分析和汇编代码生成所需变量
        //定义符号表元素结构
        public struct _Vartable
        {
            //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = IDLENGTH)]

            public string name; //符号字符串
            //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = IDLENGTH)]

            public string type; //符号类型
            public int VarAdd; //符号地址
        }
        _Vartable[] vartable=new _Vartable[MAXVARTABLENUM]; //存储符号

        int Varindex = 0;//符号的索引
        /// <summary>
        /// 总的符号数
        /// </summary>
        int VarNum = 0; 
        int labelp = 0; //标号序号
        int datap = 0; //符号地址
        public struct _Siyuanshi
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SIYUANSHI)]

            public string op;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SIYUANSHI)]

            public string  oper1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SIYUANSHI)]

            public string  oper2;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SIYUANSHI)]

            public string result;
            public int id; //四元式编号
        }

        _Siyuanshi[] siyuanshi = new _Siyuanshi[MAXSIYUANSHI];//四元式
        int siyuanshi_index = 0;// 四元式的索引
        int result_index = 0; //四元式中间结果标号
        char[] temp = new char[SIYUANSHI]; // 字符串复制中间变量
        int oper_index = 0;// 操作数的序号
        int temp_index = 1;//中间变量标号
        int nextq = 0;
        int ntc, nfc, while_s, while_e, while_t, for_s, for_e, for_t;
        string[] TempTable = new string[MAXSIYUANSHI];

        #endregion

        #region  词法分析

        public void TokenAnalysis(string path)
        {
            Table = new TokenTable
            {
                list = new Token[MAXNUM],
                index = 0,
                realNum = 0
            };
            //初始化单词表
            //索引号
            //实际单词数量
            //初始化缓冲区
            Inbuf.index = 0;
            Inbuf.realLenth = 0;

            Input(path);//读入源程序
            createLineNum();
            Console.WriteLine("程序源码：");
            Console.WriteLine(Inbuf.srcBuf);
            Console.WriteLine($"共计{lineNum[Inbuf.realLenth - 1]}行,{Inbuf.realLenth}个字符");

            //词法分析开始
            char ch = ' ';
            while (Inbuf.index < Inbuf.realLenth)
            {
                do
                {
                    ch = getNextChar();//取下一个字符
                    if (Inbuf.index > Inbuf.realLenth || ch == char.MinValue)
                    {
                        var EndTok = new Token
                        {
                            ttype = TokenType.ENDFILE,
                            str = "",
                            linenum = lineNum[Inbuf.index]
                        };

                        Table.list[Table.index] = EndTok;
                        Table.index++;
                        Table.realNum++;
                        Console.WriteLine("分析完毕");
                        return;
                    }
                } while (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t');

                backChar();//回退一个字符
                Token tok = getToken();
                //将单词放入单词表
                if (tok.ttype != TokenType.COMMENT && tok.ttype != TokenType.NULL)//单词不失注释符
                {
                    Table.list[Table.index] = tok;
                    Table.index++;
                    Table.realNum++;
                }
            }

            //return;
        }
        /// <summary>
        /// 读取源文件函数（将文件的内容读到缓存区）
        /// </summary>
        /// <param name="path">源代码文件路径</param>
        void Input(string path)
        {
            StreamReader sr = null;
            try
            {
                sr = File.OpenText(path);
                Inbuf.srcBuf = sr.ReadToEnd().ToCharArray();
                Inbuf.realLenth += Inbuf.srcBuf.Length;
            }

            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
            }
            finally
            {
                sr?.Dispose();
            }
        }
        /// <summary>
        /// 构造行号
        /// </summary>
        void createLineNum()
        {
            int temp = 1;
            for (int i = 0; i < Inbuf.realLenth; i++)
            {
                lineNum[i] = temp;
                if ('\n' == Inbuf.srcBuf[i])
                {
                    temp++;
                    lineNum[i] = temp;
                }
            }
        }
        char getNextChar() //取下一个字符
        {
            char ch = char.MinValue;
            if (Inbuf.index >= Inbuf.realLenth) return ch;
            ch = Inbuf.srcBuf[Inbuf.index];
            Inbuf.index++;
            return ch;
        }
        void backChar() //回退一个字符
        {
            if (Inbuf.index - 1 >= 0)
            {
                Inbuf.index--;
                return;
            }
            Console.WriteLine("Can't Backward Char\n");
        }
        //获取一个单词
        Token getToken()
        {
            char ch;
            var str = new char[MAXNUM];
            int i = 0;
            Token tok = new Token();
            TokenType tokType = TokenType.NULL;// 单词（内置符号） 
            scanState state = scanState.START;//缓存单词 
                                              //对单词进行判断
            while (state != scanState.DONE)
            {
                ch = getNextChar();//取下一个字符
                switch (state)
                {
                    case scanState.START:

                        if (char.IsLetter(ch)) state = scanState.INID;//如果是字母
                        else if (char.IsDigit(ch)) state = scanState.INNUM;//如果是数字
                        else if (ch == '<') state = scanState.INLTEQ;
                        else if (ch == '>') state = scanState.INGTEQ;
                        else if (ch == '=') state = scanState.INASSIGN;
                        else if (ch == '!') state = scanState.INNEQ;
                        else if (ch == '_') state = scanState.INLINE;

                        else if (ch == '+') state = scanState.INPLUS;
                        else if (ch == '-') state = scanState.INMINUS;
                        else if (ch == '/') state = scanState.INSLASH;

                        else if (ch == '*') { state = scanState.DONE; tokType = TokenType.STAR; }//state=INSTAR; 
                        else if (ch == ';') { state = scanState.DONE; tokType = TokenType.SEMI; }//state=INSEMI; 
                        else if (ch == ',') { state = scanState.DONE; tokType = TokenType.COMMA; }//state=INCOMMA; 
                        else if (ch == '(') { state = scanState.DONE; tokType = TokenType.LPAREN; }//state=INLPAREN; 
                        else if (ch == ')') { state = scanState.DONE; tokType = TokenType.RPAREN; }//state=INRPAREN; 
                        else if (ch == '[') { state = scanState.DONE; tokType = TokenType.LSQUAR; }//state=INLSQUAR; 
                        else if (ch == ']') { state = scanState.DONE; tokType = TokenType.RSQUAR; }//state=INRSQUAR; 
                        else if (ch == '{') { state = scanState.DONE; tokType = TokenType.LBRACE; }//state=INLBRACE; 
                        else if (ch == '}') { state = scanState.DONE; tokType = TokenType.RBRACE; }//state=INRBRACE; 
                        else if (ch == '"') { state = scanState.DONE; tokType = TokenType.QMARKS; }//tokType=QMARKS
                        else if (ch == '&') { state = scanState.DONE; tokType = TokenType.OPERATOR; }//tokType=OPERATOR
                        else if (ch == '%') { state = scanState.DONE; tokType = TokenType.POINT; }
                        else
                        {
                            Console.WriteLine("词法分析错误，在:{0} 行 {1}", lineNum[Inbuf.index], ch);
                        }
                        break;
                    case scanState.INID:
                        if (!char.IsLetter(ch) && !char.IsDigit(ch) && ch != '_')
                        {
                            backChar();
                            ch = '\0';
                            tokType = reservedlookup(str); //查找保留字
                            if (tokType == TokenType.PRINTF)
                            {
                                //printfAndscanf PS;	
                                int i1 = 0, j = 1, k = 0;
                                PSanf[PSindex].id = PSindex;
                                PSanf[PSindex].log = 1;
                                while (ch != ',')
                                {
                                    j++;
                                    ch = getNextChar();
                                    if (ch != '"' && ch != '(' && ch != ',')
                                    {
                                        PSanf[PSindex].str[i1++] = ch;
                                        //    	printf("$$%s\n",PSanf[PSindex].str);
                                    }

                                }
                                //		printf("%c\n",ch);
                                PSanf[PSindex].id = PSanf[PSindex].str.Length;
                                //	printf("%d",PSanf[PSindex].id);

                                i1 = 0;
                                ch = getNextChar();
                                while (ch != ')')
                                {

                                    j++;

                                    while (char.IsLetter(ch) || char.IsDigit(ch) || ch == '_')
                                    {
                                        PSanf[PSindex].vars[k].variable[i1++] = ch;
                                        ch = getNextChar();
                                        j++;
                                        //	printf("%c\n",ch);

                                    }
                                    PSanf[PSindex].varindex = i1 + 1;
                                    //PSanf[PSindex].vars[k].variable[i1]='\0';
                                    if (ch != ')')
                                        ch = getNextChar();
                                    i1 = 0;
                                    k++;

                                    //	printf("%s\n",PSanf[PSindex].str);
                                    //	printf("%s\n",PSanf[PSindex].vars[k-1].variable);	

                                }
                                //PSanf[PSindex].vars[k]='\0'; 
                                Inbuf.index = Inbuf.index - j;
                                ch = getNextChar();
                                PSindex++;
                                ch = '\0';


                            }

                            else if (tokType == TokenType.SCANF)
                            {
                                int i1 = 0, j = 1, k = 0;
                                PSanf[PSindex].id = PSindex;
                                PSanf[PSindex].log = 2;
                                while (ch != ',')
                                {


                                    j++;
                                    ch = getNextChar();
                                    if (ch != '"' && ch != '(' && ch != ',')
                                    {
                                        PSanf[PSindex].str[i1++] = ch;

                                    }
                                    // 		printf("%s\n",PSanf[PSindex].str);
                                }

                                PSanf[PSindex].id = PSanf[PSindex].str.Length;

                                //	printf("%d",sizeof());

                                i1 = 0;
                                ch = getNextChar();
                                while (ch != ')')
                                {

                                    j++;
                                    while (char.IsLetter(ch) || char.IsDigit(ch))
                                    {
                                        PSanf[PSindex].vars[k].variable[i1++] = ch;
                                        ch = getNextChar();
                                        j++;

                                    }
                                    PSanf[PSindex].varindex = i1 + 1;
                                    //PSanf[PSindex].vars[k].variable[i1]='\0'; 	     	 				
                                    //	printf("%s\n",PSanf[PSindex].vars[k].variable);
                                    if (ch != ')')
                                        ch = getNextChar();
                                    i1 = 0;
                                    k++;

                                }
                                //PSanf[PSindex].vars[k]='\0';
                                //	printf("%s\n",PSanf[PSindex].str);
                                Inbuf.index = Inbuf.index - j;
                                ch = getNextChar();
                                PSindex++;
                                ch = '\0';



                            }

                            state = scanState.DONE; //DONE状态                       
                        }//if结束 


                        break;
                    case scanState.INNUM:
                        if (!char.IsDigit(ch) && ch != '.')
                        {

                            index = 0;
                            if (char.IsLetter(ch) || ch == '_')//类似3____
                            {
                                Console.WriteLine("词法分析错误，在:{0} 行 {1}", lineNum[Inbuf.index], ch);
                            }
                            backChar();
                            ch = '\0';
                            tokType = TokenType.NUMBER;
                            state = scanState.DONE;

                        }

                        if (ch == '.')
                            index++;
                        if (index == 2)
                        {
                            Console.WriteLine("词法分析错误，在:{0} 行 {1}", lineNum[Inbuf.index], ch);

                        }

                        break;
                    case scanState.INLTEQ: //<       
                        if (ch == '=')
                        {
                            state = scanState.DONE;
                            tokType = TokenType.LTEQ;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.LT;
                        }
                        break;
                    case scanState.INGTEQ: //>          
                        if (ch == '=')
                        {
                            state = scanState.DONE;
                            tokType = TokenType.GTEQ;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.GT;
                        }
                        break;
                    case scanState.INASSIGN: // =        
                        if (ch == '=')
                        {
                            state = scanState.DONE;
                            tokType = TokenType.EQ;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.ASSIGN;
                        }
                        break;
                    case scanState.INNEQ: //!           
                        if (ch == '=')
                        {
                            state = scanState.DONE;
                            tokType = TokenType.NEQ;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.NEG; //取反negative
                        }
                        break;
                    case scanState.INPLUS: //+           
                        if (ch == '+') // ++
                        {
                            state = scanState.DONE;
                            tokType = TokenType.PLUS_2;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.PLUS;
                        }
                        break;
                    case scanState.INMINUS: //-
                        if (ch == '-')
                        {
                            state = scanState.DONE;
                            tokType = TokenType.MINUS_2;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.MINUS;
                        }
                        break;
                    case scanState.INSTAR://*
                        state = scanState.DONE;
                        tokType = TokenType.STAR;
                        break;
                    case scanState.INSLASH:// / 跳过注释       
                        if (ch == '*')
                        {
                            do
                            {
                                ch = getNextChar();
                                if (ch == '*' && getNextChar() == '/')
                                {
                                    break;
                                }
                            } while (true);
                            ch = '\0';
                            state = scanState.DONE;
                            // str[i--]='\0'; //过滤注释，不再记录 '/'
                            str[0] = '\0';
                            tok.ttype = TokenType.COMMENT;
                            return tok;
                        }
                        else if (ch == '/')
                        {
                            while (ch != '\n')
                            {
                                ch = getNextChar();
                            }
                            backChar();
                            state = scanState.DONE;
                            ch = '\0';
                            str[i--] = '\0'; //过滤注释，不再记录 '/'
                            str[0] = '\0';
                            tok.ttype = TokenType.COMMENT;
                            return tok;
                        }
                        else
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE;
                            tokType = TokenType.SLASH;
                        }
                        break;
                    case scanState.INLINE:
                        if (!char.IsLetter(ch) && !char.IsDigit(ch) && ch != '_')
                        {
                            backChar();
                            ch = '\0';
                            state = scanState.DONE; //DONE状态    
                            tokType = TokenType.ID;
                        }
                        break;
                } //end_switch
                str[i++] = ch; //记录当前正在判断的单词符号串
                               //str[i] = '\0';
            } //end_while

            tok.ttype = tokType;
            //str[i] = '\0';
            //tok.str = str;
            // string尾部是否有多余结束字符('\0')
            tok.str = new string(str.Where(o=>o!='\0').ToArray());
            tok.linenum = lineNum[Inbuf.index - 1];

            return tok;
        }
        TokenType reservedlookup(char[] str) //查找保留字
        {
            string id = "";
            foreach (var ch in str.Where(o => o != '\0'))
            {
                id += ch;
            }
            int i = 0;
            for (i = 0; i < 17; i++)
            {
                if (string.CompareOrdinal(id, reservedwords[i].str) == 0)
                {
                    return reservedwords[i].tok;
                }
            }
            return TokenType.ID;
        }

        #endregion
        #region 语法分析

        //语法分析
        public void parse()
        {
            //初始化单词表索引
            Table.index = 0;
            __TreeNode root = new __TreeNode();
            //TreeNode root = (pTreeNode)malloc(sizeof(TreeNode));//语法根
            //root->lineno = 0;

            curtoken = getNextToken();      //取得第一个token	   

            root = program();//递规下降分析！构建语法，并返回根节点
            Console.WriteLine("\n-----------------语法分析成功!-----------------\n");
        }
        Token getNextToken() //获取下一个token
        {
            Token tok = new Token();
            if (Table.index < Table.realNum)
            {
                tok = Table.list[Table.index++];
                if (tok.ttype != TokenType.ENDFILE)
                {
                    Console.WriteLine("语法分析通过：第{0}行  {1}", tok.linenum, tok.str);

                }
                return tok;
            }
            else
            {
                tok.ttype = TokenType.ENDFILE;
                return tok;
            }
        }
        //program→ { fun-declaration | var-declaration } 
        //只有一个主程序没有另外的函数声明
        //改为 program→ { fun-declaration }
        __TreeNode program()
        {
            //pTreeNode root = (pTreeNode)malloc(sizeof(TreeNode));//语法根
            __TreeNode funNode;
            __TreeNode root = new __TreeNode();

            funNode = root;
            funNode = fun_decl(); //函数头    
            return root;
        }
        //函数定义fun-declaration→ ( int | void ) ID( params ) compound-stmt
        __TreeNode fun_decl()
        {
            __TreeNode retnode;
            retnode = CreateNode();
            while (curtoken.ttype != TokenType.LPAREN) //(
            {
                switch (curtoken.ttype)
                {
                    case TokenType.INT: //函数返回类型int
                    case TokenType.VOID: //函数返回类型void	
                                         //记录函数返回类型              
                        retnode.rettype = curtoken.str;
                        match(curtoken.ttype);
                        break;
                    case TokenType.ID:
                        retnode.nodestr = curtoken.str;
                        match(TokenType.ID);
                        break;
                    default:
                        ParseError();
                        break;
                }
            }
            match(TokenType.LPAREN); // (
            if (curtoken.ttype != TokenType.RPAREN)
            {
                __TreeNode paramsNode = param_list();    //生成参数列表	
            }
            match(TokenType.RPAREN); // )
            __TreeNode stmtNode = compound_stmt();//函数体 
            return retnode;
        }
        __TreeNode CreateNode() //创建一个节点
        {
            return new __TreeNode();
        }
        int match(TokenType expected) //匹配当前单词类型,并且读取下一个
        {
            if (curtoken.ttype == expected)
            {
                curtoken = getNextToken();
                return 1;
            }
            else
            {
                ParseError();
                return 0;
            }
        }
        void ParseError() //语法分析错误提示
        {
            int line_Num = 0;
            line_Num = Table.list[Table.index].linenum;
            Console.WriteLine("第 {0} 行 {1}不符合语法规范", line_Num,curtoken.str);
        }
        // params → int ID { , int ID } | void | empty
        __TreeNode param_list() //生成参数列表
        {
            __TreeNode retnode, nextnode, curnode;
            retnode = curnode = CreateNode();

            while (curtoken.ttype != TokenType.RPAREN) //)
            {
                switch (curtoken.ttype)
                {
                    case TokenType.INT:
                        match(TokenType.INT);
                        break;
                    case TokenType.DOUBLE:
                        match(TokenType.DOUBLE);
                        break;
                    case TokenType.FLOAT:
                        match(TokenType.FLOAT);
                        break;
                    case TokenType.CHAR:
                        match(TokenType.CHAR);
                        break;
                    case TokenType.VOID:
                        match(TokenType.VOID);
                        break;
                    case TokenType.ID:
                        nextnode = CreateNode();
                        nextnode.nodestr = curtoken.str;
                        curnode = nextnode;
                        match(TokenType.ID);
                        break;
                    case TokenType.COMMA: // 定义多个变量		
                        match(TokenType.COMMA);
                        break;
                    default:
                        ParseError();
                        break;
                }
            }
            return retnode;
        }
        //compound-stmt→ { { var-declaration } { statement } }
        __TreeNode compound_stmt() //函数体
        {
            __TreeNode compoundNode = new __TreeNode();
            __TreeNode varNode, stmtNode, curNode;
            curNode = CreateNode();
            match(TokenType.LBRACE); // “{”
            //TODO 这里可以类型扩充范围  
            if (curtoken.ttype == TokenType.INT || curtoken.ttype == TokenType.DOUBLE || curtoken.ttype == TokenType.CHAR)
            {
                compoundNode = curNode = varNode = var_decl(); //函数体内变量声明
            }
            stmtNode = statement();
            while ((stmtNode.nodestr != null || stmtNode.rettype != null || stmtNode.vartype != null) && curtoken.ttype != TokenType.RBRACE && curtoken.ttype != TokenType.ENDFILE)
            {
                stmtNode = statement();
                curNode = stmtNode;
            }
            match(TokenType.RBRACE); // }

            return compoundNode;
        }
        //var-declaration→ int ID { , ID }    
        //可以声明多个变量(以分号未结束标记，分析一行句子)
        __TreeNode var_decl()
        {
            __TreeNode retnode = new __TreeNode(), nextnode, curnode;
            while (curtoken.ttype != TokenType.SEMI) // ; 变量声明语句结束 
            {
                retnode = curnode = CreateNode();
                switch (curtoken.ttype)
                {
                    case TokenType.INT:
                        match(TokenType.INT);
                        break;
                    case TokenType.DOUBLE:
                        match(TokenType.DOUBLE);
                        break;
                    case TokenType.FLOAT:
                        match(TokenType.FLOAT);
                        break;
                    case TokenType.CHAR:
                        match(TokenType.CHAR);
                        break;
                    case TokenType.ID:
                        nextnode = CreateNode();
                        nextnode.nodestr = curtoken.str;
                        curnode = nextnode;
                        match(TokenType.ID);
                        break;
                    case TokenType.COMMA: // 定义多个变量		
                        match(TokenType.COMMA);
                        break;
                    default:
                        ParseError();
                        break;
                }
            }
            match(TokenType.SEMI);
            return retnode;
        }
        //statement→ expression-stmt∣compound-stmt ∣if-stmt ∣while-stmt | for-stmt | return-stmt 
        __TreeNode statement() //函数体内语句序列
        {
            __TreeNode expNode, comdNode, ifNode, whileNode, forNode, reNode, scNode, prNode;
            __TreeNode stmtNode = new __TreeNode();

            switch (curtoken.ttype)
            {
                case TokenType.ID:
                    expNode = exp_stmt();      //表达式语句
                    stmtNode = expNode;
                    break; //变量
                case TokenType.NUMBER: //数字
                    expNode = exp_stmt();      //表达式语句
                    stmtNode = expNode;
                    break;
                case TokenType.SCANF:
                    scNode = scanf_stmt();      //表达式语句
                    stmtNode = scNode;
                    break;
                case TokenType.PRINTF:
                    prNode = printf_stmt();      //表达式语句
                    stmtNode = prNode;
                    break;
                case TokenType.IF:
                    ifNode = if_stmt();        //if语句
                    stmtNode = ifNode;
                    break;
                case TokenType.WHILE:
                    whileNode = while_stmt();     //while语句  
                    stmtNode = whileNode;
                    break;
                case TokenType.FOR:
                    forNode = for_stmt();       //for语句
                    stmtNode = forNode;
                    break;
                case TokenType.RETURN:
                    reNode = return_stmt();      //return语句
                    stmtNode = reNode;
                    break;
                case TokenType.LBRACE:                    //函数体
                    comdNode = compound_stmt();
                    stmtNode = comdNode;
                    break;
                default:
                    ParseError();
                    break;
            }

            return stmtNode;
        }
        //expression-stmt→ [ expression ] ;
        __TreeNode exp_stmt() //表达式语句
        {
            __TreeNode expNode;
            while (string.CompareOrdinal(curtoken.str,";")==0) //匹配空语句
            {
                match(TokenType.SEMI);
            }
            expNode = express();
            if (curtoken.ttype == TokenType.SEMI)
            {
                match(TokenType.SEMI);
            }
            else if (curtoken.ttype == TokenType.RPAREN)
            {

            }
            else
            {
                ParseError();
            }
            //	if(curtoken.ttype!=SEMI) {ParseError(); } 
            /*	if(curtoken.ttype == LPAREN)
            {
            match(LPAREN);
            }*/
            return expNode;
        }
        //expression→ ID = expression | simple-expression
        __TreeNode express() //具体表达式
        {
            __TreeNode expNode, newNode, childNode;
            expNode = CreateNode();
            childNode = CreateNode();
            childNode.nodestr = curtoken.str;// id 
            if (curtoken.ttype == TokenType.ID)
            {
                match(TokenType.ID);
            }
            if (curtoken.ttype == TokenType.ASSIGN) // =
            {
                match(TokenType.ASSIGN);//赋值语句
                expNode.nodestr = curtoken.str;// =
                newNode = express();
            }
            else
            {
                expNode = simple_expr();
            }
            return expNode;
        }
        //simple-expression→ additive-expression [ relop additive-expression ] 
        //relop → < | <= | > | >= | == | != 
        __TreeNode simple_expr() //简单表达式
        {
            __TreeNode simpleNode, additiveNode;
            simpleNode = CreateNode();
            additiveNode = CreateNode();
            simpleNode = additiveNode = additive_expr(); //生成算数表达式
            switch (curtoken.ttype)
            {
                case TokenType.LT: //<
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
                case TokenType.LTEQ:// <=
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
                case TokenType.GT: // >
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
                case TokenType.GTEQ: // >=
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
                case TokenType.NEQ:// !=
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
                case TokenType.EQ:// ==
                    additiveNode.nodestr = curtoken.str;
                    additiveNode.lineno = curtoken.linenum;
                    match(curtoken.ttype);
                    additiveNode = additive_expr();
                    simpleNode = additiveNode;
                    break;
            }
            return simpleNode;
        }
        //additive-expression→ term [( + | - ) term ]
        __TreeNode additive_expr() //算术表达式
        {
            __TreeNode additiveNode, termNode;
            additiveNode = termNode = term();

            if (curtoken.ttype == TokenType.PLUS)
            {
                additiveNode = CreateNode();
                additiveNode.nodestr = curtoken.str;
                additiveNode.lineno = curtoken.linenum;

                match(curtoken.ttype);
                termNode = term();
                additiveNode = termNode;
            }
            else if (curtoken.ttype == TokenType.MINUS) // -
            {
                additiveNode = CreateNode();
                additiveNode.nodestr = curtoken.str;
                additiveNode.lineno = curtoken.linenum;

                match(curtoken.ttype);
                termNode = term();
                additiveNode = termNode;
            }
            return additiveNode;
        }
        //term→ factor [ ( * | / ) factor ]
        __TreeNode term() //算术项
        {
            __TreeNode termNode, factorNode;
            termNode = CreateNode();
            factorNode = factor();
            if (curtoken.ttype == TokenType.STAR) // *
            {
                termNode.nodestr = curtoken.str;
                termNode.lineno = curtoken.linenum;

                match(curtoken.ttype);
                factorNode = factor();
                termNode = factorNode;
            }
            else if (curtoken.ttype == TokenType.SLASH)// /
            {
                termNode.nodestr = curtoken.str;
                termNode.lineno = curtoken.linenum;
                match(curtoken.ttype);
                factorNode = factor();
                termNode = factorNode;
            }
            return termNode;
        }
        //factor→ ( expression )| ID | NUM
        __TreeNode factor() //算术项中的因子项
        {
            __TreeNode factorNode, exprNode;
            factorNode = exprNode = CreateNode();
            switch (curtoken.ttype)
            {
                case TokenType.LPAREN:
                    match(TokenType.LPAREN);// (
                    exprNode = exp_stmt();
                    match(TokenType.RPAREN);// )
                    break;
                case TokenType.ID:
                    factorNode.nodestr = curtoken.str;
                    match(curtoken.ttype);
                    break;
                case TokenType.NUMBER:
                    factorNode.nodestr = curtoken.str;
                    match(curtoken.ttype);
                    break;
            }
            return factorNode;
        }
        //输入语句 
        __TreeNode scanf_stmt()
        {
            __TreeNode scNode, expNode, comNode;
            scNode = CreateNode();
            match(TokenType.SCANF);
            match(TokenType.LPAREN);
            match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.QMARKS)
            {
                match(TokenType.POINT);
                match(TokenType.ID);
            }
            match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.RPAREN)
            {
                match(TokenType.COMMA);
                match(TokenType.OPERATOR);
                match(TokenType.ID);
            }
            match(TokenType.RPAREN);
            match(TokenType.SEMI);
            return scNode;
        }
        //输出语句 
        __TreeNode printf_stmt()
        {
            __TreeNode prNode, nextnode, curnode;
            prNode = CreateNode();
            match(TokenType.PRINTF);
            match(TokenType.LPAREN);
            match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.QMARKS)
            {
                match(TokenType.POINT);
                match(TokenType.ID);
            }
            match(TokenType.QMARKS);
            match(TokenType.COMMA);
            match(TokenType.ID);//生成表达式节点
            while (curtoken.ttype != TokenType.RPAREN)
            {
                match(TokenType.COMMA);
                match(TokenType.ID);//生成表达式节点
            }
            match(TokenType.RPAREN);
            match(TokenType.SEMI);
            return prNode;
        }
        //if-stmt→ if( expression ) statement [else statement]
        __TreeNode if_stmt() //if语句
        {
            __TreeNode ifNode, expNode, comNode;
            ifNode = CreateNode();
            match(TokenType.IF);
            match(TokenType.LPAREN); // (    
            expNode = exp_stmt();//生成表达式节点
                                 //只是if语句
            match(TokenType.RPAREN); // )
            comNode = statement(); //if语句体
            ifNode = comNode;
            if (string.CompareOrdinal(curtoken.str, "else") == 0) //如果包含else语句
            {
                match(TokenType.ELSE); //if else 语句
                comNode = statement();
                ifNode = comNode;
            }
            return ifNode;
        }
        //while-stmt→ while( expression ) statement
        __TreeNode while_stmt() //while语句
        {
            __TreeNode whileNode, expNode, comNode;
            whileNode = CreateNode();
            match(TokenType.WHILE);
            match(TokenType.LPAREN);// (
            expNode = exp_stmt();
            match(TokenType.RPAREN); // )
            comNode = compound_stmt();
            whileNode = comNode;
            return whileNode;
        }
        //for-stmt→ for(expression;expression;expression) statement
        __TreeNode for_stmt() //for语句
        {
            __TreeNode forNode, expNode, comNode;
            match(TokenType.FOR);
            forNode = CreateNode();
            match(TokenType.LPAREN); // (
            expNode = exp_stmt();
            expNode = exp_stmt();
            expNode = exp_stmt();
            match(TokenType.RPAREN); // )
            comNode = statement();
            forNode = comNode;
            return forNode;
        }
        //return-stmt→ return [ expression ] ;
        __TreeNode return_stmt() //return语句
        {
            __TreeNode retNode, expNode;
            retNode = CreateNode();
            match(TokenType.RETURN);
            expNode = exp_stmt();
            retNode = expNode;
            return retNode;
        }
        #endregion
        #region 语义分析和汇编代码生成

        //语法分析入口程序
        public void code()
        {
            //初始化单词表索引
            Table.index = 0;
            int i = 0;
            curtoken = NextToken();      //取得第一个token       

            _program();//递规下降分析！

            Console.WriteLine("符号表：\n");
            showVarTabel();
            Console.WriteLine("\n-------------------四元式如下：-------------------\n");
            show_siyuanshi();
            Console.WriteLine("\n-------------------汇编代码生成成功!-------------------\n");
            Console.WriteLine("汇编代码如下：\n");
            asmcode();
        }
        Token NextToken() //获取下一个token
        {
            var tok=new Token();
            if (Table.index < Table.realNum)
            {

                tok = Table.list[Table.index];
                Table.index++;
                return tok;
            }
            else
            {
                tok.ttype = TokenType.ENDFILE;
                return tok;
            }
        }
        void _program()
        {
            _fun_decl();
            return;
        }
        // program→ { fun-declaration }

        //函数定义fun-declaration→ ( int | void ) ID( params ) compound-stmt
        void _fun_decl()
        {
            int paddress;
            int chain=-1;//不知道代表什么
            while (curtoken.ttype != TokenType.LPAREN) //(
            {
                switch (curtoken.ttype)
                {
                    case TokenType.INT: //函数返回类型int
                    case TokenType.VOID: //函数返回类型void           
                        _match(curtoken.ttype);
                        break;
                    case TokenType.ID:
                        if (lookupTable(curtoken.str,out paddress) != 0)
                        {
                            insertTable(curtoken.str, "FunDecl"); //将函数名存进符号表                
                        }
                        _match(TokenType.ID);
                        break;
                    default:
                        ParseError();
                        break;
                }// end_switch  
            }// end_while
            _match(TokenType.LPAREN); // (
            if (curtoken.ttype != TokenType.RPAREN)  //匹配参数列表,第1个子节点   
            {
                _param_list();   //生成参数列表        
            }
            _match(TokenType.RPAREN); // )
            _compound_stmt(chain);//函数体，第2个子节点
        }
        int lookupTable(string name,out int paddress) //查询符号表并且返回地址
        {
            paddress = -1;
            int i, es = 0;
            for (i = 0; i < VarNum; i++)
            {
                if (string.CompareOrdinal(vartable[i].name, name) == 0)
                {
                    paddress = vartable[i].VarAdd;
                    return es;
                }
            }
            es = 23; //变量没有声明
            return es;
        }
        int insertTable(string name, string type) //插入符号表
        {
            int i, es = 0;
            if (VarNum >= MAXVARTABLENUM)
            {
                Console.WriteLine("符号表容量太小，无法继续存储\n");
                return 21;
            }
            for (i = VarNum - 1; i == 0; i--)
            {
                if (string.CompareOrdinal(vartable[i].name, name) == 0)
                {
                    es = 22;  //22 表示变量重定义
                    break;
                }
            }
            if (es > 0) //出错/重定义→返回
            {
                return es;
            }
             vartable[Varindex].name=name; //把变量存进符号表
            setVarType(type);
            vartable[Varindex].VarAdd = datap;
            datap++; //地址增加
            Varindex++; //符号的索引增加
            VarNum++; //符号数量增加    
            return es;
        }
        void setVarType(string type) //设置符号类型
        {
             vartable[Varindex].type=type;
            return;
        }
        void showVarTabel() //显示符号表
        {
            int i = 0;
            Console.WriteLine("序号\t名字\t类型\t地址");
            for (i = 0; i < VarNum; i++)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}", i + 1,vartable[i].name, vartable[i].type, vartable[i].VarAdd);
            }
            return;
        }
        int _match(TokenType expected) //匹配当前单词类型,并且读取下一个
        {
            if (curtoken.ttype == expected)
            {
                curtoken = NextToken();
                return 1;
            }
            else
            {
                ParseError();
                return 0;
            }
        }
        // params → int ID { , int ID } | void | empty
        void _param_list() //生成参数列表
        {
            int paddress=-1;
            while (curtoken.ttype != TokenType.RPAREN)//)
            {
                switch (curtoken.ttype)
                {
                    case TokenType.INT:
                        _match(TokenType.INT);
                        break;
                    case TokenType.DOUBLE:
                        _match(TokenType.DOUBLE);
                        break;
                    case TokenType.FLOAT:
                        _match(TokenType.FLOAT);
                        break;
                    case TokenType.CHAR:
                        _match(TokenType.CHAR);
                        break;
                    case TokenType.VOID:
                        _match(TokenType.VOID);
                        break;
                    case TokenType.COMMA: // 定义多个变量      
                        _match(TokenType.COMMA);
                        break;
                    case TokenType.ID:
                        if (lookupTable(curtoken.str,out paddress) != 0)
                        {
                            insertTable(curtoken.str, curtoken.ttype.ToString());
                        }
                        break;
                    default:
                        ParseError();
                        break;
                }
            }
            return;
        }
        //compound-stmt→ { { var-declaration } { statement } }
        void _compound_stmt(int chain) //函数体
        {
            _match(TokenType.LBRACE); // {
            if (curtoken.ttype == TokenType.INT || curtoken.ttype == TokenType.DOUBLE
                || curtoken.ttype == TokenType.FLOAT | curtoken.ttype == TokenType.CHAR)
            {
                _var_decl(); //函数体内变量声明
            }
            _statement(chain);
            while (curtoken.ttype != TokenType.RBRACE && curtoken.ttype != TokenType.ENDFILE)
            {
                _statement(chain);
            }
            _match(TokenType.RBRACE); // }   
        }
        //var-declaration→ int ID { , ID }    //可以声明多个变量
        void _var_decl()
        {
            int paddress;
            while (curtoken.ttype != TokenType.SEMI) // ; 变量声明语句结束 
            {
                switch (curtoken.ttype)
                {
                    case TokenType.INT:
                        _match(TokenType.INT);
                        break;
                    case TokenType.DOUBLE:
                        _match(TokenType.DOUBLE);
                        break;
                    case TokenType.FLOAT:
                        _match(TokenType.FLOAT);
                        break;
                    case TokenType.CHAR:
                        _match(TokenType.CHAR);
                        break;
                    case TokenType.ID:
                        if (lookupTable(curtoken.str, out paddress) != 0)
                        {
                            insertTable(curtoken.str, curtoken.ttype.ToString());
                        }
                        _match(TokenType.ID);
                        break;
                    case TokenType.COMMA: // 定义多个变量      
                        _match(TokenType.COMMA);
                        break;
                    default:
                        ParseError();
                        break;
                }//end_wswitch
            }// end_while
            _match(TokenType.SEMI);
            return;
        }
        //statement→ expression-stmt∣compound-stmt ∣if-stmt 
        //∣while-stmt | for-stmt | return-stmt 
        string _statement(int chain) //函数体内语句序列
        {
            string expNode,  ifNode,  scanfNode,  printfNode,  whileNode,  forNode,  reNode;
            string stmtNode = "";
            int paddress;
            switch (curtoken.ttype)
            {
                case TokenType.ID:
                    if (lookupTable(curtoken.str, out paddress) != 0)
                    {
                        insertTable(curtoken.str, curtoken.ttype.ToString());
                    }
                    expNode = _exp_stmt(chain);     //表达式语句
                    stmtNode = expNode;
                    break; //变量
                case TokenType.NUMBER: //数字
                case TokenType.SCANF:
                    scanfNode = _scanf_stmt(chain);        //if语句
                    stmtNode = scanfNode;
                    break;
                case TokenType.PRINTF:
                    printfNode = _printf_stmt(chain);        //if语句
                    stmtNode = printfNode;
                    break;
                case TokenType.IF:
                    ifNode = _if_stmt(chain);        //if语句
                    stmtNode = ifNode;
                    break;
                case TokenType.WHILE:
                    whileNode = _while_stmt(chain);       //while语句 
                    stmtNode = whileNode;
                    break;
                case TokenType.FOR:
                    forNode = _for_stmt(chain);       //for语句
                    stmtNode = forNode;
                    break;
                case TokenType.RETURN:
                    reNode = _return_stmt(chain);       //return语句
                    stmtNode = reNode;
                    break;
                case TokenType.LBRACE://{
                    _compound_stmt(chain);       //函数体
                    break;
                default:
                    ParseError();
                    break;
            }//end-switch   
            return stmtNode;
        }
        string _scanf_stmt(int chain)
        {
            string scNode = "";
            string num1 = "";
            //char *ch1="";	
            _match(TokenType.SCANF);
            //emit("$","/","/","/"); 
            _match(TokenType.LPAREN);
            _match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.QMARKS)
            {
                _match(TokenType.POINT);
                _match(TokenType.ID);
                //emit("$","/","%d","/"); 
            }
            _match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.RPAREN)
            {
                _match(TokenType.COMMA);
                _match(TokenType.OPERATOR);
                num1 = curtoken.str;
                emit("$", "/", "%d", num1);
                _match(TokenType.ID);

            }
            _match(TokenType.RPAREN);
            _match(TokenType.SEMI);
            return scNode;

        }
        void emit(string op, string oper1, string oper2, string result) //生成一个四元式
        {
             siyuanshi[siyuanshi_index].op=op;
             siyuanshi[siyuanshi_index].oper1= oper1;
             siyuanshi[siyuanshi_index].oper2= oper2;
             siyuanshi[siyuanshi_index].result= result;
            siyuanshi[siyuanshi_index].id = siyuanshi_index + 1;

            siyuanshi_index++; //四元式编号加1
            nextq++;//四元式编号
        }
        string _printf_stmt(int chain)
        {
            string prNode = "";
            string num1 = "";

            _match(TokenType.PRINTF);
            //emit("&","/","/","/"); 
            _match(TokenType.LPAREN);
            _match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.QMARKS)
            {
                _match(TokenType.POINT);
                _match(TokenType.ID);

                //emit("&","/","%d","/"); 
            }
            _match(TokenType.QMARKS);
            while (curtoken.ttype != TokenType.RPAREN)
            {
                _match(TokenType.COMMA);
                num1 = curtoken.str;
                emit("&", "/", "%d", num1);
                _match(TokenType.ID);//生成表达式节点


            }
            _match(TokenType.RPAREN);
            _match(TokenType.SEMI);
            return prNode;
        }
        //if-stmt→ if( expression ) statement [else statement]
        string _if_stmt(int chain) //if语句
        {
            string ifNode = null, expNode,  comNode;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";
            _match(TokenType.IF);
            _match(TokenType.LPAREN); // (    
            expNode = _simple_expr(chain);//生成表达式节点
             num1=expNode;
            ntc = nextq; //记住if语句位置
            emit("FJ", "", num1, "/"); //按假跳转
            _match(TokenType.RPAREN); // )    
            comNode = _statement(chain); //if语句体    
            nfc = nextq;
            emit("RJ", "", "/", "/");
            backFill(ntc, nextq + 1);  ////ntc链接的所有四元式都回填nextq
            if (string.CompareOrdinal(curtoken.str, "else") == 0) //如果包含else语句
            {
                _match(TokenType.ELSE);
                comNode = _statement(chain);
            }
            backFill(nfc, nextq + 1);  ////nfc链接的所有四元式都回填nextq
            return num1;
        }
        //simple-expression→ additive-expression [ relop additive-expression ]
        //relop → < | <= | > | >= | == | != 
        string _simple_expr(int chain) //简单表达式
        {
            string additiveNode;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";

            additiveNode = _additive_expr(chain); //生成算数表达式
             num1=additiveNode;
            switch (curtoken.ttype)
            {
                case TokenType.LT: //<        
                     op="<";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2=additiveNode;
                     result=newTemp();//生成一个临时变量Tn赋给result
                    emit(op, num1, num2, result);
                    return result;
                    break;
                case TokenType.LTEQ:// <=                
                     op="<=";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2=additiveNode;
                     result= newTemp();
                    emit(op, num1, num2, result);
                    return result;
                    break;
                case TokenType.GT: // >
                     op= ">";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2=additiveNode;
                     result=newTemp();
                    emit(op, num1, num2, result);
                    return result;
                    break;
                case TokenType.GTEQ: // >=     
                     op=">=";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2=additiveNode;
                     result=newTemp();
                    emit(op, num1, num2, result);
                    return result;
                    break;
                case TokenType.NEQ:// !=      
                     op= "!=";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2= additiveNode;
                     result= newTemp();
                    emit(op, num1, num2, result);
                    return result;
                    break;
                case TokenType.EQ:// ==      
                     op= "==";
                    _match(curtoken.ttype);
                    additiveNode = _additive_expr(chain);
                     num2= additiveNode;
                     result= newTemp();
                    emit(op, num1, num2, result);
                    return result;
                    break;
            }
            return num1;
        }
        //additive-expression→ term [( + | - ) term ]
        string _additive_expr(int chain) //算术表达式
        {
            string termNode;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";

            termNode = _term(chain);
             num1= termNode;
            if (curtoken.ttype == TokenType.PLUS)
            {
                 op= "+";
                _match(curtoken.ttype);
                termNode = _term(chain);
                 num2= termNode;
                 result= newTemp();
                emit(op, num1, num2, result);
                return result;
            }
            else if (curtoken.ttype == TokenType.MINUS)
            {
                 op= "-";
                _match(curtoken.ttype);
                termNode = _term(chain);
                 num2= termNode;
                 result= newTemp();
                emit(op, num1, num2, result);
                return result;
            }
            return num1;
        }
        //term→ factor [ ( * | / ) factor ]
        string _term(int chain) //算术项
        {
            string factorNode;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";

            factorNode = _factor(chain);
             num1= factorNode;
            if (curtoken.ttype == TokenType.STAR)
            {
                 op= "*";
                _match(curtoken.ttype);
                factorNode = _factor(chain);
                 num2= factorNode;
                 result= newTemp();
                emit(op, num1, num2, result);
                return result;
            }
            else if (curtoken.ttype == TokenType.SLASH)
            {
                 op= "/";
                _match(curtoken.ttype);
                factorNode = _factor(chain);
                 num2= factorNode;
                 result= newTemp();
                emit(op, num1, num2, result);
                return result;
            }
            return num1;
        }
        //factor→ ( expression )| ID | NUM
        string _factor(int chain) //算术项中的因子项
        {

            string factorNode;
            int paddress;
            factorNode = "";
            switch (curtoken.ttype)
            {
                case TokenType.LPAREN://(
                    _match(TokenType.LPAREN);
                    factorNode = _simple_expr(chain);
                    _match(TokenType.RPAREN);//)
                    break;
                case TokenType.ID:
                    if (lookupTable(curtoken.str, out paddress) != 0)
                    {
                        insertTable(curtoken.str, curtoken.ttype.ToString());
                    }
                     factorNode= curtoken.str;
                    _match(curtoken.ttype);
                    break;
                case TokenType.NUMBER:
                    if (lookupTable(curtoken.str, out paddress) != 0)
                    {
                        insertTable(curtoken.str, curtoken.ttype.ToString());
                    }
                     factorNode= curtoken.str;
                    _match(curtoken.ttype);
                    break;
            }
            return factorNode;
        }
        string newTemp() //生成四元式中间变量T1，T2...
        {
            string temp  = string.Format("T{0}", temp_index);

             TempTable[temp_index]= temp; //存入中间变量表
            temp_index++;

            return temp;
        }
        //while-stmt→ while( expression ) statement
        string _while_stmt(int chain) //while语句
        {
            string whileNode = "",  expNode;
            _match(TokenType.WHILE);
            _match(TokenType.LPAREN);// (    
            while_s = nextq; //while条件的开始   
            expNode = _simple_expr(chain);
            while_e = nextq; //while循环体的开始
            emit("FJ", "", expNode, "/");
            _match(TokenType.RPAREN); // )
            _compound_stmt(chain);
            while_t = nextq;
            emit("RJ", "", "/", "/");
            backFill(while_t, while_s + 1);
            backFill(while_e, nextq + 1);
            return whileNode;
        }
        void backFill(int p, int t) //回填,将p所链接的每个四元式的第二分量都回填t
        {
            int w, circle = p;
            while (circle!=0) //circle不为0的时候
            {
                //四元式第2分量内容
                if (!int.TryParse(siyuanshi[circle].oper1, out w))
                    w = 0;
                siyuanshi[circle].oper1 = t.ToString();

                //sprintf(siyuanshi[circle].oper1, "%d", t);
                circle = w; //w记录的是链条上下一个四元式，移动！circle=w=0
            }
        }
        //for-stmt→ for(expression;expression;expression) statement
        string _for_stmt(int chain) //for语句
        {
            string forNode = "";
            string expNode,  comNode;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";
            _match(TokenType.FOR);
            _match(TokenType.LPAREN); // (
            expNode = _exp_stmt(chain);
            for_s = nextq; //记录for语句转化为if的开始位置
            expNode = _exp_stmt(chain);
            emit("FJ", "", expNode, "/");
            expNode = _exp_stmt(chain);
            _match(TokenType.RPAREN); // )
            comNode = _statement(chain);
            for_e = nextq;
            emit("RJ", "", "/", "/");
            backFill(for_e, for_s + 1);
            backFill(for_s + 1, nextq + 1);
            return forNode;
        }
        //return-stmt→ return [ expression ] ;
        string _return_stmt(int chain) //return语句
        {
            string expNode;
            _match(TokenType.RETURN);
            emit("RET", " ", " ", " ");
            expNode = _exp_stmt(chain);
            int qq = siyuanshi_index - 1;
             siyuanshi[qq].oper1= " ";
            return expNode;
        }
        //expression-stmt→ [ expression ] ;
        string _exp_stmt(int chain) //表达式语句
        {
            string expNode;
            while (string.CompareOrdinal(curtoken.str, ";") == 0) //匹配空语句
            {
                _match(TokenType.SEMI);
            }
            expNode = _express(chain);
            if (curtoken.ttype == TokenType.SEMI)
            {
                _match(TokenType.SEMI);
            }
            if (curtoken.ttype == TokenType.LPAREN)
            {
                _match(TokenType.LPAREN);
            }
            return expNode;
        }
        //expression→ ID = expression | simple-expression
        string _express(int chain) //具体表达式
        {
            string newNode,  expNode="";
            int paddress;
            string result = "";
            string num1 = "";
            string num2 = "";
            string op = "";
            if (curtoken.ttype == TokenType.ID)
            {
                if (lookupTable(curtoken.str, out paddress) != 0)
                {
                    insertTable(curtoken.str, curtoken.ttype.ToString());
                }
                TokenType tem_tok = NextToken().ttype;
                backToken();
                if (tem_tok != TokenType.ASSIGN)
                {
                     num1= curtoken.str;
                }
                else
                {
                     result= curtoken.str; //结果
                }

                _match(TokenType.ID);
            }
            if (curtoken.ttype == TokenType.ASSIGN)
            {
                 op= "=";

                _match(TokenType.ASSIGN);
                newNode = _simple_expr(chain);
                 num1= newNode;
                 num2= "/";
                emit(op, num1, num2, result);
            }
            else
            {
                int qq = siyuanshi_index;
                expNode = _simple_expr(chain);

                 siyuanshi[qq].oper1= num1;
            }
            return expNode;
        }
        void backToken() //退回一个token
        {
            if (Table.index - 1 >= 0)
            {
                Table.index--;
            }
            return;
        }

        void show_siyuanshi() //显示四元式列表
        {
            int i = 0;
            for (i = 0; i < siyuanshi_index; i++)
            {
                Console.WriteLine("{0}: ({1},{2},{3},{4})", siyuanshi[i].id,
                    siyuanshi[i].op, siyuanshi[i].oper1,
                    siyuanshi[i].oper2, siyuanshi[i].result);
            }
            return;
        }
        void asmcode() //生成汇编代码
        {
            int i;
            asmHead();
            for (i = 0; i < siyuanshi_index; i++)
            {
                int flag = 0;
                if (siyuanshi[i].oper1.Contains(siyuanshi_index.ToString()))
                {
                     siyuanshi[i].oper1= "TheEnd"; //标记程序段的结束
                    flag = 1;
                }
                if (string.CompareOrdinal(siyuanshi[i].op, "=") == 0)
                {

                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   mov {0},Ax", siyuanshi[i].result);
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "$") == 0)
                {
                    Console.WriteLine("SCANF:");
                    Console.WriteLine("L{0}:lea dx,{1}", i + 1, siyuanshi[i].result);
                    Console.WriteLine("mov ah,9");
                    Console.WriteLine("int 21H");

                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "&") == 0)
                {
                    Console.WriteLine("Console.WriteLine:");
                    Console.WriteLine("L{0}:lea dx,{1}", i + 1, siyuanshi[i].result);
                    Console.WriteLine("mov ah,9\n");
                    Console.WriteLine("INT 21H\n");

                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "+") == 0)
                {
                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   add Ax,{0}", siyuanshi[i].oper2);
                    Console.WriteLine("   mov {0},Ax", siyuanshi[i].result);
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "-") == 0)
                {
                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   sub Ax,{0}", siyuanshi[i].oper2);//sub被减数大进位相减
                    Console.WriteLine("   mov {0},Ax", siyuanshi[i].result);
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "*") == 0)
                {
                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   mov BX,{0}", siyuanshi[i].oper2);
                    Console.WriteLine("   mul BX\n");
                    Console.WriteLine("   mov {0},Ax", siyuanshi[i].result);
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "/") == 0)
                {
                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   mov BX,{0}", siyuanshi[i].oper2);
                    Console.WriteLine("   div BX");
                    Console.WriteLine("   mov {0},AL", siyuanshi[i].result);
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "FJ") == 0)
                {
                    if (flag == 1)
                    {
                        Console.WriteLine("L{0}:jnc {1}", i + 1, siyuanshi[i].oper1);//jnc无进位跳转
                    }
                    else
                    {
                        Console.WriteLine("L{0}:jnc L{1}", i + 1, siyuanshi[i].oper1);
                    }

                }
                else if (string.CompareOrdinal(siyuanshi[i].op, "RJ") == 0)
                {
                    if (flag == 1)
                    {
                        Console.WriteLine("L{0}:jmp {1}", i + 1, siyuanshi[i].oper1);//jmp无条件跳转
                    }
                    else
                    {
                        Console.WriteLine("L{0}:jmp L{1}", i + 1, siyuanshi[i].oper1);
                    }
                }
                else if (string.CompareOrdinal(siyuanshi[i].op, ">") == 0 || string.CompareOrdinal(siyuanshi[i].op, ">=") == 0
                    || string.CompareOrdinal(siyuanshi[i].op, "<") == 0 || string.CompareOrdinal(siyuanshi[i].op, "<=") == 0)
                {
                    Console.WriteLine("L{0}:mov AX,{1}", i + 1, siyuanshi[i].oper1);
                    Console.WriteLine("   sub Ax,{0}", siyuanshi[i].oper2);
                }

            }
            Console.WriteLine("TheEnd:nop\n");//空指令，空操作
            asmTail();
        }
        void asmHead() //打印汇编代码头部
        {
            int i, j;
            Console.WriteLine("assume cs:codesg,ds:datasg");
            Console.WriteLine("datasg segment"); //划分数据段
            for (i = 0; i < VarNum; i++) //为符号表中的变量分配空间
            {
                if (string.CompareOrdinal(vartable[i].type, "ID") == 0)
                {
                    Console.WriteLine("\t{0} dw 0", vartable[i].name);
                }
            }
            for (j = 1; j < temp_index; j++)
            {
                Console.WriteLine("\t{0} dw 0", TempTable[j]);
            }
            Console.WriteLine("datasg ends");
            Console.WriteLine("codesg segment");
            Console.WriteLine("start:");
        }
        void asmTail() //打印汇编代码尾部
        {
            Console.WriteLine("mov ax,4c00h");
            Console.WriteLine("int 21h");
            Console.WriteLine("codesg ends");
            Console.WriteLine("end start");

            return;
        }
        #endregion

    }
}




















//多出来的方法？？？？？？？？？



//int ergeFour(int p1,int p2) //合并p1和p2
//{
//char circle,nResult;
//if(p2==0)
//nResult=p1;
//else
//{
//nResult=circle=p2;
//while(atoi(siyuanshi[circle].oper1)) //四元式第2个分量不为0
//{
//circle=atoi(siyuanshi[circle].oper1);

//sprintf(siyuanshi[circle].oper1,"%s",p1);
//}
////目的是用p1的值覆盖0
//}
//return nResult; //p2是头，p1覆盖0，接在p2后边
//}
//*/



